#include "scrambled_symbols.h"
#include "conversion.h"
#include "smartarrpointer.hxx"

/*/////////////////////////////////////////////////////////////////////////////
//
///////////*/
tUInt16 Byte2Hex(tByte value)
{
  register unsigned int n;
  short int res; /* 16 bits integer. */
  char *hex_value;

  n=0;
  res=0;
  hex_value=(char *)&res;

  n=(value>>4)&15;
  if (n<10) hex_value[0]=(char) n+'0';
  else hex_value[0]=(char) n+('A'-10);

  n=(value&15);
  if (n<10) hex_value[1]=(char)n+'0';
  else hex_value[1]=(char)n+('A'-10);

  return res;
}

/*/////////////////////////////////////////////////////////////////////////////
//
///////////*/
tByte Hex2Byte(const tByte value[2])
{
  register unsigned int n;
  register unsigned int i;
  n=0;

  i=value[0];

  switch(i)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      {
	n=i-'0';
      }
      break;

    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
      {
	n=i-'a'+10;
      }
      break;

    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case 'E':
    case 'F':
      {
	n=i-'A'+10;
      }
      break;
    }

  n=n<<4;

  i=value[1];

  switch(i)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      {
	n=n+(i-'0');
      }
      break;

    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
      {
	n=n+(i-'a'+10);
      }
      break;

    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case 'E':
    case 'F':
      {
	n=n+(i-'A'+10);
      }
      break;
    }

  return n;
}



void Bin2Ascii(tByte *binbuf, tUInt32 len, tByte *out)
{
  tUInt32 i;
  tUInt16 *pdest;
  tByte *pdestfinal;
  tByte *psource;
  for (i=0,pdest=(tUInt16 *) out,psource=binbuf; i<len; i++, psource++, pdest++)
    {
      *pdest=Byte2Hex(*psource);
    }
  // We have to write one NULL byte! So we need to cast pointer from 16 bits to 8 bits!
  // Do not use *pdest=0 which would have written 16 bits and so made an invalid write 
  // of one byte out of the buffer.
  pdestfinal=(tByte *) pdest;
  *pdestfinal=0;
}

tByte *sBin2Ascii(tByte *binbuf, tUInt32 len)
{
  // We use Smart Array Pointer for automatic memory release.
  static SmartArrPointer<tByte> _inner_buf;
  static tUInt32 _inner_buf_len=0;
  static tUInt32 _max_allowed_len=0;

  if (_inner_buf.Null())
    {
      _max_allowed_len=len;
      _inner_buf_len=(len<<1)+1;
      _inner_buf=new tByte[_inner_buf_len];
    }
  else
    {
      if (_max_allowed_len<len)
	{
	  // Release previous memory buffer.
	  _inner_buf.SetNull();

	  _max_allowed_len=len;
	  _inner_buf_len=(len<<1)+1;
	  _inner_buf=new tByte[_inner_buf_len];
	}
    }

  Bin2Ascii(binbuf,len,*_inner_buf);

  return *_inner_buf;
}


void Ascii2Bin(tByte *asciibuf, tUInt32 len, tByte *out)
{
  tUInt32 i;
  tByte *pdest;
  tUInt16 *psource;

  for (i=0,pdest=asciibuf,psource=(tUInt16 *) out; i<len; i++, psource++, pdest++)
    {
      *pdest=Hex2Byte((tByte *) psource);
    }
}



